//////////////////////////////////////////////////////////////////////////
//Author	: Ross Conroy ross.conroy@tees.ac.uk
//Date		: 15/05/2014
//
//This executable uses the BWAPI to watch replays and extract data about
//the game play from the replays for later use in data mining
//////////////////////////////////////////////////////////////////////////

#include <stdio.h>
#include <BWAPI.h>
#include <BWAPI/Client.h>
#include <windows.h>
#include <string>
#include <iostream>
#include "extractData.h"
#include <sstream>
#include "ExtractData2.h"

using namespace BWAPI;
using namespace std;

vector<string> argumentToVector(string argument)
{
	vector<string> arguments;
	argument = argument.substr(1, argument.length()-2);

	if(argument.length() > 0)
	{
		stringstream ss;
		ss << argument << ",";

		argument = ss.str();

		string temp;
		while (argument.find(",", 0) != string::npos)
		{
			size_t  pos = argument.find(",", 0);
			temp = argument.substr(0, pos);
			argument.erase(0, pos + 1);

			arguments.push_back(temp);
		}
	}

	return arguments;
}

void reconnect()
{
  while(!BWAPIClient.connect())
  {
    Sleep(1000);
  }
}

int main(int argc, const char* argv[])
{
	//Parse command line parameters

	if (argc > 1) // New command line friendly method can set parameters such as time step duration
	{
		//cout << "USEAGE [outputDirectory] [Unit Types] <time step duration>" << endl;
		string outputDirectory = argv[1];
		vector<string> unitTypes = argumentToVector(argv[2]); //ToDo extract csv to vector
		int timeStepDuration = -1;
		if(argc > 3)
		{
			timeStepDuration = atoi(argv[3]);
		}		

		BWAPI::BWAPI_init();
		printf("Connecting...");
		reconnect();
		while(true)
		{
			cout << "Waiting for replay to start" << endl;
			while ( !Broodwar->isInGame() )
			{
				BWAPI::BWAPIClient.update();
				if (!BWAPI::BWAPIClient.isConnected())
				{
					cout << "Reconnecting..." << endl;;
					reconnect();
				}
			}	

			ExtractData2 extractor(outputDirectory, unitTypes, timeStepDuration);

			std::cout << "Starting Replay" << std::endl;
			std::cout << "The map is " << Broodwar->mapName() << ", a " << Broodwar->getStartLocations().size() << " player map" << std::endl;
			std::cout << "The following players are in this replay:" << endl;
			for(std::set<Player*>::iterator p=Broodwar->getPlayers().begin();p!=Broodwar->getPlayers().end();p++)
			{
				if (!(*p)->getUnits().empty() && !(*p)->isNeutral())
				{
					cout << (*p)->getName() << ", playing as a " << (*p)->getRace().getName() << endl;
				}
			}

			while(Broodwar->isInGame())
			{
				extractor.Tick();
				BWAPI::BWAPIClient.update();
				if (!BWAPI::BWAPIClient.isConnected())
				{
					printf("Reconnecting...\n");
					reconnect();
				}
			}
			extractor.Save();
			cout << "Saving replay data" << endl;
		}
	}
	else //No parameters use old methods
	{
		BWAPI::BWAPI_init();
		printf("Connecting...");
		reconnect();
		while(true)
		{
			cout << "Waiting for replay to start" << endl;
			while ( !Broodwar->isInGame() )
			{
				BWAPI::BWAPIClient.update();
				if (!BWAPI::BWAPIClient.isConnected())
				{
					cout << "Reconnecting..." << endl;;
					reconnect();
				}
			}	

			if (Broodwar->isReplay())
			{
				ExtractData extractData;
				string dataFile = "C:\\StarcraftReplayData\\";
				stringstream ss;
				ss << dataFile;
				//ss << Broodwar->mapName();

				std::cout << "Starting Replay" << std::endl;
				std::cout << "The map is " << Broodwar->mapName() << ", a " << Broodwar->getStartLocations().size() << " player map" << std::endl;
				std::cout << "The following players are in this replay:" << endl;
				for(std::set<Player*>::iterator p=Broodwar->getPlayers().begin();p!=Broodwar->getPlayers().end();p++)
				{
					if (!(*p)->getUnits().empty() && !(*p)->isNeutral())
					{
						cout << (*p)->getName() << ", playing as a " << (*p)->getRace().getName() << endl;
						ss << "[" << (*p)->getName() << "_" << (*p)->getRace().getName() << "]";
					}
				}

				ss << ".csv";
				dataFile = ss.str();

				while(Broodwar->isInGame())
				{
					//TODO Extract data
					extractData.Tick();

					BWAPI::BWAPIClient.update();
					if (!BWAPI::BWAPIClient.isConnected())
					{
						printf("Reconnecting...\n");
						reconnect();
					}
				}

				cout << "Saving replay data" << endl;
				extractData.SaveData(dataFile);
				cout << "Replay Ended Data Saved to >>" << dataFile << endl;
			}
			else
			{
				cout << "Not a replay, Replay Data Extractor only valid for replay playback" << endl;
			}
	}  
	
  }
  //system("pause");
  return 0;
}